from django.db import models
from django.db.models import Avg, Max, Min, Count
from plugins.AutoFileField import AutoFileField

# holds user info
class User(models.Model):
	ACCOUNT_STATUS_CHOICES = ((1, u'Active'), (2, 'Deleted'))

	username = models.CharField(max_length=30, unique=True, db_index=True, help_text='30 characters max', verbose_name='User Name')
        password = models.CharField(max_length=30, help_text='minimum 6 characters', verbose_name='Password')
        firstname = models.CharField(max_length=25, help_text='25 characters max', verbose_name='First Name')
        lastname = models.CharField(max_length=25, help_text = '25 character max', verbose_name='Last Name')
	email = models.EmailField(max_length=200, unique=True, db_index=True, verbose_name='Email ID')
        affiliation = models.CharField(max_length=200, verbose_name='Organization')
        home_page_url = models.CharField(max_length=300, verbose_name='Home Page URL', blank=True, null=True)
	account_status = models.PositiveSmallIntegerField(default=1, verbose_name='Profile status', choices=ACCOUNT_STATUS_CHOICES)
        regdate = models.DateTimeField(auto_now_add=True, verbose_name='Profile registration date')
        last_modified = models.DateTimeField(auto_now=True, verbose_name='Profile Last modified time')
        last_login = models.DateTimeField(auto_now_add=True, verbose_name='Profile last login time')

	def save(self):
                self.firstname = self.firstname.capitalize()
                self.lastname = self.lastname.capitalize()
		if self.home_page_url != None and self.home_page_url != '' and not self.home_page_url.startswith('http://'):
			self.home_page_url = 'http://' + self.home_page_url
		
                #save
                super(User, self).save()


class Project(models.Model):
	user = models.ForeignKey('User', related_name='Projects_Created')
	name =  models.CharField(max_length=100, help_text='100 characters max', verbose_name='Project Name', null=False, blank=False)
	description = models.CharField(max_length=1000, help_text='1000 characters max', verbose_name='Description', null=True, blank=True)
	shared_object = models.ForeignKey('SharedObject')
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')
        last_modified = models.DateTimeField(auto_now=True, verbose_name='Last modified time')

	def save(self, *args, **kwargs):
                self.name = self.name.capitalize()
                super(Project, self).save(*args, **kwargs)

	def delete(self):
		self.shared_object.delete()
		super(Project, self).delete()


class User_Project(models.Model):
	user = models.ForeignKey('User', related_name='Projects')
	project = models.ForeignKey('Project', related_name='Users')
	permission = models.ManyToManyField('Static_User_Permission', null=True, blank=True)
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Rgistration date')
        last_modified = models.DateTimeField(auto_now=True, verbose_name='Last modified time')

	class Meta:
		unique_together = (('user', 'project'),)

class Static_User_Permission(models.Model):
	name = models.CharField(max_length=100)
	description = models.CharField(max_length=300, null=True, blank=True)
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')

class SharedObject(models.Model):
	SHARING_CHOICES = ((0, u'Private'), (1, u'Read Only'), (2, u'Open to All'))

	SharedObjectType = models.ForeignKey('SharedObjectType')
	user = models.ForeignKey('User', related_name='SharedObjectsOwned')
	description = models.CharField(max_length=300)
	sharing_permission = models.PositiveSmallIntegerField(default=0, choices=SHARING_CHOICES)
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')
	last_modified = models.DateTimeField(auto_now=True, verbose_name='Last modified time')
	

class SharedObjectType(models.Model):
	type = models.CharField(max_length=100)
	description = models.CharField(max_length=1000)
	internal_table_name = models.CharField(max_length=100)
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')

class Corpora(models.Model):
	STATUS_CHOICES = ((1, u'Active'), (2, u'Inactive'), (3, u'Processing'), (4, u'Invalid File'))

	name = models.CharField(max_length=100)
	description = models.CharField(max_length=2000, blank=True, null=True)
	status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=2)
	project = models.ForeignKey('Project', related_name='Corpora')
	user = models.ForeignKey('User', related_name='Corpora_Uploaded')
	corpus_file = AutoFileField(max_length=400, upload_to='TextBadger/Corpora/')
	schema_file = AutoFileField(max_length=400, upload_to='TextBadger/Schema/', null=True, blank=True)	
	shared_object = models.ForeignKey('SharedObject')
	num_docs = models.PositiveIntegerField(null=True, blank=True)
	parent_corpus = models.ForeignKey('Corpora', null=True, blank=True, related_name='ChildCorpora')
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')
        last_modified = models.DateTimeField(auto_now=True, verbose_name='Last modified time')

	def save(self, *args, **kwargs):
                self.name = self.name.capitalize()
                super(Corpora, self).save(*args, **kwargs)


class Document(models.Model):
	corpus = models.ForeignKey('Corpora', related_name='Documents')
	filename = AutoFileField(max_length=400, upload_to='TextBadger/Documents/')
		

class Codebook(models.Model):
	TYPE_CHOICES = ((1, u'XML built'), (2, 'Web Interface built'))
	STATUS_CHOICES = ((1, u'Active'), (2, u'Inactive'), (3, u'Processing'), (4, u'Invalid File'))

	name = models.CharField(max_length=100)
	status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=2)
	type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, default=1)
	codebook_file = AutoFileField(max_length=400, upload_to='TextBadger/Codebooks/', null=True, blank=True)
	schema_file = AutoFileField(max_length=400, upload_to='TextBadger/Schema/', null=True, blank=True)
	user = models.ForeignKey('User', related_name='Codebooks_Created')
	project = models.ForeignKey('Project', related_name='Codebooks')
	shared_object = models.ForeignKey('SharedObject')
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')
        last_modified = models.DateTimeField(auto_now=True, verbose_name='Last modified time')

	def save(self, *args, **kwargs):
                self.name = self.name.capitalize()					
                super(Codebook, self).save(*args, **kwargs)


class Codebook_Question(models.Model):
	TYPE_CHOICES = ((1, u'Text Based'), (2, u'Multiple Choice, Single Select'), (3, u'Multiple Choice, Multiple Select'))

	codebook = models.ForeignKey('Codebook', related_name='Questions')
	question_type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES)
	question_text = models.CharField(max_length=500)	
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')
	last_modified = models.DateTimeField(auto_now=True, verbose_name='Last modified time')
	
class Codebook_Question_Choice(models.Model):
	codebook_question = models.ForeignKey('Codebook_Question', related_name='Choices')
	text = models.CharField(max_length=500)


class Vectorizer_Algo(models.Model):
	STATUS_CHOICES = ((1, u'Active'), (2, u'Inactive'), (3, u'Processing'), (4, u'Invalid File'))

        status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=2)
	name = models.CharField(max_length=200)
	filename = AutoFileField(upload_to='TextBadger/VectorizersAlgo/')
	user = models.ForeignKey('User', null=True, blank=True, related_name='Vectorizers_Algo_Uploaded')
	project = models.ForeignKey('Project', null=True, blank=True, related_name='Vectorizers_Algo_Uploaded')
	shared_object = models.ForeignKey('SharedObject', null=True, blank=True)
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')
	
	def save(self, *args, **kwargs):
                self.name = self.name.capitalize()
                super(Vectorizer_Algo, self).save(*args, **kwargs)


class Classifier_Algo(models.Model):
	STATUS_CHOICES = ((1, u'Active'), (2, u'Inactive'), (3, u'Processing'), (4, u'Invalid File'))

        status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=2)
	name = models.CharField(max_length=200)
	filename = AutoFileField(upload_to='TextBadger/ClassifiersAlgo/')
	user = models.ForeignKey('User', null=True, blank=True, related_name='Classifiers_Algo_Uploaded')
	project = models.ForeignKey('Project', null=True, blank=True, related_name='Classifiers_Algo_Uploaded')
	shared_object = models.ForeignKey('SharedObject', null=True, blank=True)
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')

	def save(self, *args, **kwargs):
                self.name = self.name.capitalize()
                super(Classifier_Algo, self).save(*args, **kwargs)


class Corpus_Vector(models.Model):
	STATUS_CHOICES = ((1, u'Completed'), (2, u'Not Started'), (3, u'Started'), (4, u'Error'))

        status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=2)
	name = models.CharField(max_length=200)
	corpus = models.ForeignKey('Corpora', related_name='Vectors')
	project = models.ForeignKey('Project', related_name='Vectors')
	shared_object = models.ForeignKey('SharedObject')
	vectorizer_algo = models.ForeignKey('Vectorizer_Algo', related_name='Vectors_Created')
	filename = AutoFileField(upload_to='TextBadger/Vectors/', null=True, blank=True)
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')

	def save(self, *args, **kwargs):
                self.name = self.name.capitalize()
                super(Corpus_Vector, self).save(*args, **kwargs)

class Notification(models.Model):
	TYPE_CHOICES = ((1, u'Message'), (2, u'Email'))
	STATUS_CHOICES = ((1, u'Unread'), (2, u'Read'))

	sender = models.ForeignKey('User', related_name='Messages_Sent')
	receiver = models.ForeignKey('User', related_name='Messages_Received')
	text = models.CharField(max_length=2000)
	type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, default=1)
	status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=1)
	is_starred = models.BooleanField(default=False)
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')


class ReportGenerator(models.Model):
	STATUS_CHOICES = ((1, u'Active'), (2, u'Inactive'), (3, u'Processing'), (4, u'Invalid File'))

        status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=2)
	name = models.CharField(max_length=200)
	filename = AutoFileField(upload_to='TextBadger/ReportGenerators/')
	user = models.ForeignKey('User', null=True, blank=True, related_name='ReportGenerator_Algo_Uploaded')
        project = models.ForeignKey('Project', null=True, blank=True, related_name='ReportGenerator_Algo_Uploaded')
	shared_object = models.ForeignKey('SharedObject', null=True, blank=True)
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')

	def save(self, *args, **kwargs):
                self.name = self.name.capitalize()
                super(ReportGenerator, self).save(*args, **kwargs)


class Report(models.Model):
	STATUS_CHOICES = ((1, u'Completed'), (2, u'Not Started'), (3, u'Started'), (4, u'Error'))

        status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=2)
	name = models.CharField(max_length=200)
	filename = AutoFileField(upload_to='TextBadger/Reports/', null=True, blank=True)
	project = models.ForeignKey('Project', related_name='Reports')
	job = models.ForeignKey('Job')
	user = models.ForeignKey('User', related_name='Reports_Generated')
	reportgenerator = models.ForeignKey('ReportGenerator', related_name='Reports_Created')
	shared_object = models.ForeignKey('SharedObject')
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')
	
	def save(self, *args, **kwargs):
                self.name = self.name.capitalize()
                super(Report, self).save(*args, **kwargs)


class Task(models.Model):
	STATUS_CHOICES = ((1, u'Completed'), (2, u'Not Started'), (3, u'Started'))
	
	status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=2)
	name = models.CharField(max_length=200)
	corpus = models.ForeignKey('Corpora', related_name='Assigned_Labellers')
	codebook = models.ForeignKey('Codebook', related_name='Assigned_Labellers')
	user = models.ForeignKey('User', related_name='Tasks')
	project = models.ForeignKey('Project', related_name='Tasks')
	assigner = models.ForeignKey('User', related_name='TasksCreated')
	shared_object = models.ForeignKey('SharedObject', null=True, blank=True)
	num_docs = models.PositiveIntegerField(default=0)
	minrange = models.PositiveIntegerField(default=1)
	maxrange = models.PositiveIntegerField(default=-1) # -1 means all the documents
	num_docs_completed = models.PositiveIntegerField(default=0)
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')

	def save(self, *args, **kwargs):
                self.name = self.name.capitalize()
                super(Task, self).save(*args, **kwargs)


class Job(models.Model):
	STATUS_CHOICES = ((1, u'Completed'), (2, u'Not Started'), (3, u'Started'), (4, u'Error'))

        status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=2)
	name = models.CharField(max_length=200)
	project = models.ForeignKey('Project', related_name='Jobs')
	user = models.ForeignKey('User', related_name='Jobs_Scheduled')
        tasks = models.ManyToManyField('Task', related_name='Jobs')
        classifier_algo = models.ForeignKey('Classifier_Algo', related_name='AssociatedJobs')
	vectorizer_algo = models.ForeignKey('Vectorizer_Algo', related_name='AssociatedJobs', null=True, blank=True)
	classifier_args = models.CharField(max_length=1000, null=True, blank=True)
	vectorizer_args = models.CharField(max_length=1000, null=True, blank=True)
	corpus_vector = models.ForeignKey('Corpus_Vector', related_name='AssociatedJobs', null=True, blank=True)
	classifier = models.ForeignKey('Classifier', null=True, blank=True, related_name='AssociatedJob')
        regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')

	def save(self, *args, **kwargs):
                self.name = self.name.capitalize()
                super(Job, self).save(*args, **kwargs)

class Classifier(models.Model):
	filename = AutoFileField(upload_to='TextBadger/Classifiers/')
	project = models.ForeignKey('Project', related_name='Classifiers')
	shared_object = models.ForeignKey('SharedObject')
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')


class TaskDocumentResponse(models.Model):
	task = models.ForeignKey('Task', related_name='DocumentResponses')
	document = models.ForeignKey('Document', related_name='TaskResponses')


class Labelling(models.Model):
	taskdocument = models.ForeignKey('TaskDocumentResponse', related_name='Labellings')
	codebook_question = models.ForeignKey('Codebook_Question', related_name='Labellings')
	coded_value = models.CharField(max_length=200, blank=True, null=True) # for text based ques
	coded_choices = models.ManyToManyField('Codebook_Question_Choice', null=True, blank=True, related_name='mchoice') # for mcq ques
	coded_choice = models.ForeignKey('Codebook_Question_Choice', null=True, blank=True, related_name='schoice')
	regdate = models.DateTimeField(auto_now_add=True, verbose_name='Registration date')


